
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 部署src/*_src.jar
 */
public class DeploySrc {

    private final Path FROM_SRC;
    private final Path TO_MODULES;
    private final Path TO_EXTERNAL_CLASSES;

    private final PathMatcher nccloudMatcher = FileSystems.getDefault().getPathMatcher("glob:nccloud*/src/client/**/*.{java}");
    private final PathMatcher publicMatcher = FileSystems.getDefault().getPathMatcher("glob:*/src/public/**/*.{java}");
    private final PathMatcher privateMatcher = FileSystems.getDefault().getPathMatcher("glob:*/src/private/**/*.{java}");


    public DeploySrc(String FIELD_NC_HOME) {
        FROM_SRC = Paths.get(FIELD_NC_HOME, "src");
        TO_MODULES = Paths.get(FIELD_NC_HOME, "modules");
        TO_EXTERNAL_CLASSES = Paths.get(FIELD_NC_HOME, "external/classes");
    }

    public static void run(String home) throws IOException {
		new DeploySrc(home.strip()).run();
	}

    public void run() throws IOException {
        copyJava();
    }


    private void copyJava() throws IOException {
        File[] fromFiles = FROM_SRC.toFile().listFiles();
        for (File fromFile : fromFiles) {
            if (fromFile.getName().endsWith(".jar")) {
                _doCopy(fromFile);
            }

        }

        System.out.println(">>> move src/*_src.jar success");
    }

    private void _doCopy(File fromFile) throws IOException {

        // fa_src.jar
        final String moduleName = fromFile.getName().split("_", 2)[0];
        // fa\classes
        final Path publicClassesPath = TO_MODULES.resolve(Paths.get(moduleName, "classes"));
        // fa\META-INF\classes
        final Path privateClassesPath = TO_MODULES.resolve(Paths.get(moduleName, "META-INF/classes"));

        try (JarFile jarFile = new JarFile(fromFile);) {
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry jarEntry = entries.nextElement();
                _fileVisiter(publicClassesPath, privateClassesPath, jarFile, jarEntry);
            }
        }

        System.out.println(">>> move src/" + fromFile.getName() + " success");
    }

    private void _fileVisiter(final Path publicClassesPath, final Path privateClassesPath, JarFile jarFile, JarEntry jarEntry) throws IOException {
        String filename = jarEntry.getName();

        if (filename.endsWith(".java")) {

            Path filepath = Paths.get(filename);
            if (nccloudMatcher.matches(filepath)) {

                Path prefix = filepath.subpath(0, 3);
                Path relativize = prefix.relativize(filepath);

                Path target = TO_EXTERNAL_CLASSES.resolve(relativize);
                target.getParent().toFile().mkdirs();

                Files.copy(jarFile.getInputStream(jarEntry), target, StandardCopyOption.REPLACE_EXISTING);

            } else if (publicMatcher.matches(filepath)) {

                Path prefix = filepath.subpath(0, 3);
                Path relativize = prefix.relativize(filepath);

                Path target = publicClassesPath.resolve(relativize);
                target.getParent().toFile().mkdirs();

                Files.copy(jarFile.getInputStream(jarEntry), target, StandardCopyOption.REPLACE_EXISTING);

            } else if (privateMatcher.matches(filepath)) {

                Path prefix = filepath.subpath(0, 3);
                Path relativize = prefix.relativize(filepath);

                Path target = privateClassesPath.resolve(relativize);
                target.getParent().toFile().mkdirs();

                Files.copy(jarFile.getInputStream(jarEntry), target, StandardCopyOption.REPLACE_EXISTING);

            }
        }
    }

}
